package hk.edu.polyu.comp.motioncapture;

//import hk.edu.polyu.comp.motioncapture.analysis.sequence.PointTrack;
import hk.edu.polyu.comp.motioncapture.point.*;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class CameraControl extends Thread {
	private FrameSet frameSetPlayer1;
	private Screen screen;
	private boolean isInitScreenCheckPoint = false;
	private Point checkPt[] = new Point[4];

	static boolean isRunning;

	// SR
	public boolean hasSoundCommand;
	public String soundCommand = "";

	// Need track sound / point
	boolean point;
	boolean sound;

	Date startTime;

	/**
	 * Creates an motion capture camera.
	 */
	public CameraControl() {
		// Create Point Vector
		this(true, true, null);
	}

	/**
	 * Create an camera object
	 * 
	 * @param point
	 *            - Accept Point Recognition
	 * @param sound
	 *            - Accept Speech Recognition
	 */
	public CameraControl(boolean point, boolean sound, Screen screen) {
		// Create Point Vector
		frameSetPlayer1 = new FrameSet(5000, 1000);

		this.screen = screen;
		this.point = point;
		this.sound = sound;

		isRunning = false;
	}

	/**
	 * Start the camera.
	 * 
	 * @throws IOException
	 */
	public void run() {

		try {
			storeCoordinates();

		} catch (Exception ex) {
			System.out.println(ex);
		}

	}

	/**
	 * Reads the coordinates and store in a Vector of Point.Double array.
	 * 
	 * @throws IOException
	 */
	public void storeCoordinates() throws Exception {

		try {
			ServerSocket serverSocket = null;
			Socket clientSocket = null;
			PrintWriter out = null;
			BufferedReader in = null;
			String inputLine;

			ServerSocket srServerSocket = null;
			Socket srSocket = null;
			PrintWriter out2 = null;
			BufferedReader in2 = null;
			String inputLine2;

			if (point) {

				serverSocket = new ServerSocket(8000);
				clientSocket = serverSocket.accept();
				out = new PrintWriter(clientSocket.getOutputStream(), true);
				in = new BufferedReader(new InputStreamReader(clientSocket
						.getInputStream()));
				System.out.println("Accept point");

				isRunning = true;
			}

			// SR
			if (sound) {

				srServerSocket = new ServerSocket(43420);
				srSocket = srServerSocket.accept();
				out2 = new PrintWriter(srSocket.getOutputStream(), true);
				in2 = new BufferedReader(new InputStreamReader(srSocket
						.getInputStream()));
				System.out.println("Accept sound");
			}

			while (isRunning) {

				if (!isInitScreenCheckPoint) {
					if (screen.isExist()) {
						checkPt[0] = screen.getTopLeftPoint();
						checkPt[1] = screen.getTopRightPoint();
						checkPt[2] = screen.getBottomLeftPoint();
						checkPt[3] = screen.getBottomRightPoint();
						isInitScreenCheckPoint = true;
					}

				}

				if (point) {

					inputLine = in.readLine();

					int arrayCounter = 1;

					String[] tempAry = inputLine.split(" ");

					// Create the number of Point array
					int noOfPoint = ((tempAry.length - 1) / 2);
					Frame p = new Frame(5, 1);

					for (int i = 0; i < noOfPoint; i++) {

						// Read the current checking point
						double x = Double.parseDouble(tempAry[arrayCounter]);
						arrayCounter++;
						double y = Double.parseDouble(tempAry[arrayCounter]);
						arrayCounter++;

						Point temp = new OptiPoint(x, y);

						// Check with the screen
						// boolean isScreenPt = false;
						//						
						// if(isInitScreenCheckPoint)
						// {
						// for(int j=0; j<4; j++)
						// {
						// if(PointTrack.isInRegion(10, checkPt[j], temp))
						// isScreenPt = true;
						// }
						// }
						//						
						// if(!isScreenPt)
						p.add(temp);
					}
					if (frameSetPlayer1.size() == 0)
						startTime = new Date();

					frameSetPlayer1.add(p);

				}

				if (sound) {
					if (in2.ready()) {
						if ((inputLine2 = in2.readLine()) != null) {
							hasSoundCommand = true;
							soundCommand = inputLine2;
							System.out.println(soundCommand);
						}
					}
				} else {
					hasSoundCommand = false;
				}
			}

			if (point) {
				out.close();
				in.close();
				clientSocket.close();
				serverSocket.close();
			}

			if (sound) {
				out2.close();
				in2.close();
				srSocket.close();
				srServerSocket.close();
			}

		} catch (Exception e) {
			// e.printStackTrace();
		}

	}

	/**
	 * Stop the camera.
	 */
	public void stopCarema() {
		isRunning = false;
	}

	/**
	 * Return true when the camera is still running
	 */
	public boolean isRunning() {
		return (isRunning);
	}

	public FrameSet getPlayer() {
		return frameSetPlayer1;
	}

	public static void main(String[] args) {
		// CameraControl cc = new CameraControl(true, false);
		// cc.start();
	}
}
